// TextureGeneratorDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TextureGenerator.h"
#include "TextureGeneratorDlg.h"
#include "resourcebrowserdlg.h"
#include "texgen.h"
#include "texgenprimitives.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define D_SIZE TSIZE
#define T_SIZE TSIZE

BITMAPINFO *bitmap_header;
static char bitmapbuffer[sizeof(BITMAPINFO)+16];
int32 tempbild[T_SIZE*T_SIZE];

void preparedraw() {
	memset(bitmapbuffer,0,sizeof(BITMAPINFO)+16);
	bitmap_header = (BITMAPINFO *)bitmapbuffer;
	bitmap_header->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitmap_header->bmiHeader.biPlanes = 1;
	bitmap_header->bmiHeader.biBitCount = 32;
	bitmap_header->bmiHeader.biCompression = BI_BITFIELDS;
	bitmap_header->bmiHeader.biWidth = T_SIZE;
	bitmap_header->bmiHeader.biHeight = -T_SIZE; // note well
	((unsigned long *)bitmap_header->bmiColors)[0] = 0x00FF0000;
	((unsigned long *)bitmap_header->bmiColors)[1] = 0x0000FF00;
	((unsigned long *)bitmap_header->bmiColors)[2] = 0x000000FF;
}

void drawdata(HDC hdc, int32 *data, int _x, int _y) {
	StretchDIBits(hdc, _x, _y, D_SIZE, D_SIZE,
		0, 0, T_SIZE, T_SIZE, data, bitmap_header, DIB_RGB_COLORS, SRCCOPY);
}
void drawdata_alpha(HDC hdc, int32 *data, int _x, int _y) {
	for (int i=0; i<T_SIZE*T_SIZE; i++) {
		int c=data[i]>>24;
		tempbild[i] = c | (c<<8) | (c<<16) | (c<<24);
	}
	StretchDIBits(hdc, _x, _y, D_SIZE, D_SIZE,
		0, 0, T_SIZE, T_SIZE, tempbild, bitmap_header, DIB_RGB_COLORS, SRCCOPY);
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

	// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

	// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTextureGeneratorDlg dialog

CTextureGeneratorDlg::CTextureGeneratorDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTextureGeneratorDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTextureGeneratorDlg)
	m_Filename = _T("");
	m_Param1LabelText = _T("");
	m_Param2LabelText = _T("");
	m_Param3LabelText = _T("");
	m_Param4LabelText = _T("");
	m_MaskA = FALSE;
	m_MaskB = FALSE;
	m_MaskG = FALSE;
	m_MaskR = FALSE;
	m_NameParamLabelText = _T("");
	m_DisplayAlpha = FALSE;
	m_TexID = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTextureGeneratorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTextureGeneratorDlg)
	DDX_Control(pDX, IDC_BROWSE, m_BrowseButton);
	DDX_Control(pDX, IDC_FILENAME, m_FilenameBox);
	DDX_Control(pDX, IDC_ACTIONS, m_ActionList);
	DDX_Control(pDX, IDC_SELECTACTION, m_SelectActionList);
	DDX_Control(pDX, IDC_NAMEPARAMLABEL, m_NameParamLabel);
	DDX_Control(pDX, IDC_PARAMLABEL4, m_Param4Label);
	DDX_Control(pDX, IDC_PARAMLABEL3, m_Param3Label);
	DDX_Control(pDX, IDC_PARAMLABEL2, m_Param2Label);
	DDX_Control(pDX, IDC_PARAMLABEL1, m_Param1Label);
	DDX_Control(pDX, IDC_PARAM4, m_Param4Slider);
	DDX_Control(pDX, IDC_PARAM3, m_Param3Slider);
	DDX_Control(pDX, IDC_PARAM2, m_Param2Slider);
	DDX_Control(pDX, IDC_PARAM1, m_Param1Slider);
	DDX_Control(pDX, IDC_OPLIST, m_OpList);
	DDX_Control(pDX, IDC_LAYERLIST3, m_DataLayer2List);
	DDX_Control(pDX, IDC_LAYERLIST2, m_DataLayerList);
	DDX_Control(pDX, IDC_LAYERLIST1, m_CurLayerList);
	DDX_Text(pDX, IDC_FILENAME, m_Filename);
	DDV_MaxChars(pDX, m_Filename, 4);
	DDX_Text(pDX, IDC_PARAMLABEL1, m_Param1LabelText);
	DDX_Text(pDX, IDC_PARAMLABEL2, m_Param2LabelText);
	DDX_Text(pDX, IDC_PARAMLABEL3, m_Param3LabelText);
	DDX_Text(pDX, IDC_PARAMLABEL4, m_Param4LabelText);
	DDX_Check(pDX, IDC_MASKA, m_MaskA);
	DDX_Check(pDX, IDC_MASKB, m_MaskB);
	DDX_Check(pDX, IDC_MASKG, m_MaskG);
	DDX_Check(pDX, IDC_MASKR, m_MaskR);
	DDX_Text(pDX, IDC_NAMEPARAMLABEL, m_NameParamLabelText);
	DDX_Check(pDX, IDC_DISPLAYALPHA, m_DisplayAlpha);
	DDX_Text(pDX, IDC_TEXID, m_TexID);
	DDV_MaxChars(pDX, m_TexID, 4);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTextureGeneratorDlg, CDialog)
	//{{AFX_MSG_MAP(CTextureGeneratorDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_COMMAND(ID_FILE_EXIT, OnFileExit)
	ON_COMMAND(ID_HELP_ABOUT, OnHelpAbout)
	ON_BN_CLICKED(IDC_APPLY, OnApply)
	ON_WM_HSCROLL()
	ON_WM_TIMER()
	ON_WM_LBUTTONDOWN()
	ON_BN_CLICKED(IDC_UNDO, OnUndo)
	ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
	ON_COMMAND(ID_FILE_NEWTEXTURE, OnFileNewTexture)
	ON_COMMAND(ID_FILE_OPENTEXTURE, OnFileOpenTexture)
	ON_COMMAND(ID_FILE_SAVETEXTURE, OnFileSaveTexture)
	ON_WM_RBUTTONDOWN()
	ON_BN_CLICKED(IDC_REDO, OnRedo)
	ON_BN_CLICKED(IDC_DISPLAYALPHA, OnDisplayAlpha)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTextureGeneratorDlg message handlers

BOOL CTextureGeneratorDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	//SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here

	m_CurLayerList.AddString("1 (top left)");
	m_CurLayerList.AddString("2 (top right)");
	m_CurLayerList.AddString("3 (bottom left)");
	m_CurLayerList.AddString("4 (bottom right)");

	m_DataLayerList.AddString("1 (top left)");
	m_DataLayerList.AddString("2 (top right)");
	m_DataLayerList.AddString("3 (bottom left)");
	m_DataLayerList.AddString("4 (bottom right)");

	m_DataLayer2List.AddString("1 (top left)");
	m_DataLayer2List.AddString("2 (top right)");
	m_DataLayer2List.AddString("3 (bottom left)");
	m_DataLayer2List.AddString("4 (bottom right)");

	m_OpList.AddString("= (equal)");
	m_OpList.AddString("* (multiply)");
	m_OpList.AddString("+ (add)");
	m_OpList.AddString("- (subtract)");
	m_OpList.AddString("^ (xor)");

	for (int i=0; i<32; i++) {
		m_SelectActionList.AddString(actioninfo[i].name);
	}
	//m_CurLayerList.AddString("4");

	m_Param1Slider.SetRange(0,255,0);
	m_Param2Slider.SetRange(0,255,0);
	m_Param3Slider.SetRange(0,255,0);
	m_Param4Slider.SetRange(0,255,0);

	m_MaskA = 0;
	m_MaskR = 1;
	m_MaskG = 1;
	m_MaskB = 1;

	m_CurLayerList.SetCurSel(0);
	m_DataLayerList.SetCurSel(0);
	m_DataLayer2List.SetCurSel(0);
	m_OpList.SetCurSel(0);
	m_SelectActionList.SetCurSel(0);
	//OnHScroll(0,0,0);
	updatelabels();
	UpdateData(FALSE);

	Texgen::Texgen_Init();
	preparedraw();
	SetTimer(0,10,0);
	settitle("Untitled");
	//  load_resources();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTextureGeneratorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTextureGeneratorDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CPaintDC dc(this); // device context for painting
		if (m_DisplayAlpha) {
			drawdata_alpha(dc, generator.getlayer(0), 0,0);
			drawdata_alpha(dc, generator.getlayer(1), D_SIZE+2,0);
			drawdata_alpha(dc, generator.getlayer(2), 0,D_SIZE+2);
			drawdata_alpha(dc, generator.getlayer(3), D_SIZE+2,D_SIZE+2);
		}
		else {
			drawdata(dc, generator.getlayer(0), 0,0);
			drawdata(dc, generator.getlayer(1), D_SIZE+2,0);
			drawdata(dc, generator.getlayer(2), 0,D_SIZE+2);
			drawdata(dc, generator.getlayer(3), D_SIZE+2,D_SIZE+2);
		}
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTextureGeneratorDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTextureGeneratorDlg::OnFileExit() 
{
	OnCancel();
}

void CTextureGeneratorDlg::OnHelpAbout() 
{
	CAboutDlg about;
	about.DoModal();
}

void CTextureGeneratorDlg::OnApply() 
{
	SetCursor(LoadCursor(NULL, IDC_WAIT));
	UpdateData(TRUE);
	CString text;
	m_OpList.GetText(m_OpList.GetCurSel(),text);
	char colorop=text[0];

	int layer=m_CurLayerList.GetCurSel();
	int data1=m_DataLayerList.GetCurSel();
	int data2=m_DataLayer2List.GetCurSel();
	Action action;
	action.type=m_SelectActionList.GetCurSel();
	ActionInfo ai = actioninfo[action.type];

	char8 m=0;
	if (m_MaskB) m|=1;
	if (m_MaskG) m|=2;
	if (m_MaskR) m|=4;
	if (m_MaskA) m|=8;

	action.mask=m;
	action.op=colorop;
	action.layer=layer;
	//zeroes if not used to save space (will compress better probably)
	action.data1=ai.usedata1 ? data1 : 0;
	action.data2=ai.usedata2 ? data2 : 0;
	action.param1=(ai.numparams>0) ? m_Param1Slider.GetPos() : 0;
	action.param2=(ai.numparams>1) ? m_Param2Slider.GetPos() : 0;
	action.param3=(ai.numparams>2) ? m_Param3Slider.GetPos() : 0;
	action.param4=(ai.numparams>3) ? m_Param4Slider.GetPos() : 0;

	// action.nameparam = (ai.nameparamname==0) ? 0 : STRING2ID(m_Filename);

	generator.add_and_execute(action);
	generator.tolist(m_ActionList);

	m_ActionList.SetCurSel(generator.count()-1);
	InvalidateRect(CRect(0,0,(D_SIZE+2)*2,(D_SIZE+2)*2),0);
	OnPaint();
	SetCursor(0);
}


void CTextureGeneratorDlg::updatelabels() {
	int sel=m_SelectActionList.GetCurSel();
	ActionInfo ai = actioninfo[sel];

	p1label=ai.param1name;
	if (ai.param1name==0) { m_Param1Slider.ShowWindow(FALSE);  m_Param1Label.ShowWindow(FALSE); }
	else { 
		m_Param1Slider.ShowWindow(TRUE);  
		m_Param1Label.ShowWindow(TRUE); 
		if (CString(ai.param1name).Find("(8)",0)!=-1)
			m_Param1Slider.SetRange(0,8,1);
		else
			m_Param1Slider.SetRange(0,255,1);
	}

	p2label=ai.param2name;
	if (ai.param2name==0) { m_Param2Slider.ShowWindow(FALSE);  m_Param2Label.ShowWindow(FALSE); }
	else { 
		m_Param2Slider.ShowWindow(TRUE);  
		m_Param2Label.ShowWindow(TRUE); 
		if (CString(ai.param2name).Find("(8)",0)!=-1)
			m_Param2Slider.SetRange(0,8,1);
		else
			m_Param2Slider.SetRange(0,255,1);
	}

	p3label=ai.param3name;
	if (ai.param3name==0) { m_Param3Slider.ShowWindow(FALSE);  m_Param3Label.ShowWindow(FALSE); }
	else { 
		m_Param3Slider.ShowWindow(TRUE);  
		m_Param3Label.ShowWindow(TRUE); 
		if (CString(ai.param3name).Find("(8)",0)!=-1)
			m_Param3Slider.SetRange(0,8,1);
		else
			m_Param3Slider.SetRange(0,255,1);
	}

	p4label=ai.param4name;
	if (ai.param4name==0) { m_Param4Slider.ShowWindow(FALSE);  m_Param4Label.ShowWindow(FALSE); }
	else { 
		m_Param4Slider.ShowWindow(TRUE);  
		m_Param4Label.ShowWindow(TRUE); 
		if (CString(ai.param4name).Find("(8)",0)!=-1)
			m_Param4Slider.SetRange(0,8,1);
		else
			m_Param4Slider.SetRange(0,255,1);
	}

	char temp[8];
	m_Param1LabelText = p1label + ": " + itoa(m_Param1Slider.GetPos(),temp,10);
	m_Param2LabelText = p2label + ": " + itoa(m_Param2Slider.GetPos(),temp,10);
	m_Param3LabelText = p3label + ": " + itoa(m_Param3Slider.GetPos(),temp,10);
	m_Param4LabelText = p4label + ": " + itoa(m_Param4Slider.GetPos(),temp,10);

	m_DataLayerList.EnableWindow(ai.usedata1 ? 1 : 0);
	m_DataLayer2List.EnableWindow(ai.usedata2 ? 1 : 0);

	if (ai.nameparamname==0) {
		m_FilenameBox.ShowWindow(FALSE);
		m_NameParamLabel.ShowWindow(FALSE);
		m_BrowseButton.ShowWindow(FALSE);
	}
	else {
		m_FilenameBox.ShowWindow(TRUE);
		m_NameParamLabel.ShowWindow(TRUE);
		m_BrowseButton.ShowWindow(TRUE);
		m_NameParamLabelText = ai.nameparamname;
	}
}

void CTextureGeneratorDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	updatelabels();
	UpdateData(FALSE);
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}


void CTextureGeneratorDlg::OnTimer(UINT nIDEvent) 
{
	UpdateData(TRUE);
	updatelabels();
	UpdateData(FALSE);

	CDialog::OnTimer(nIDEvent);
}


//these are to prevent ESC and RETURN from closing the texgen (which is.. irritating :)
void CTextureGeneratorDlg::OnOK() {}

void CTextureGeneratorDlg::OnCancel() {
	if (MessageBox("Exit now?","Exit?",MB_YESNO)==IDYES)
		CDialog::OnCancel();
}

void CTextureGeneratorDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int x=point.x;
	int y=point.y;
	x>>=8;
	y>>=8;
	if (x>=2 || y>=2) return;
	int num=(x&1) + (y?2:0);
	m_CurLayerList.SetCurSel(num);
	updatelabels();
	UpdateData(FALSE);
	CDialog::OnLButtonDown(nFlags, point);
}


void CTextureGeneratorDlg::OnBrowse() 
{
	CResourceBrowserDlg dialog;
	dialog.DoModal();
	if (dialog.ok) {
		//    int32 id=resources[dialog.selected].ID;
		//    m_Filename=ID2STRING(id);
		UpdateData(FALSE);
	}
}

void CTextureGeneratorDlg::OnFileNewTexture() 
{
	// TODO: Add your command handler code here
	if (IDYES==MessageBox("Are you sure you want to start over?","Sure?",MB_YESNO)) {
		generator.startover();
		generator.tolist(m_ActionList);
		InvalidateRect(CRect(0,0,T_SIZE*2+4,T_SIZE*2+4),0);
		settitle("Untitled");
	} 
}

void CTextureGeneratorDlg::OnFileOpenTexture() {
	OPENFILENAME s;
	char filename[256];
	char file[256];
	char filter[256];
	memset(filename,0,256);
	memset(&s,0,sizeof(s));
	memset(file,0,256);
	memset(filter,0,256);

	s.lStructSize=sizeof(s);
	s.hwndOwner = *this;
	s.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	//wildcard to display, returns with selected path\file
	strcpy(file,"*.6tx");
	s.lpstrFile = file;
	s.nMaxFile = 255;
	//returns with just file name
	s.lpstrFileTitle = filename;
	s.nMaxFileTitle = 255;
	//set the initial directory, otherwise uses current
	s.lpstrInitialDir = 0;
	//file type filter
	strcpy(filter,"Texture Scripts\0*.6tx\0\0");

	s.lpstrFilter = filter;
	s.nFilterIndex = 1;
	//dialog title
	s.lpstrTitle = "Open Texture Script";

	int res= GetOpenFileName(&s);

	if (res) {
		SetCursor(LoadCursor(NULL, IDC_WAIT));
		int32 ID=0; //STRING2ID("xxxx");
		generator.load(file,ID);
		//    m_TexID = ID2STRING(ID);
		UpdateData(false);
		generator.tolist(m_ActionList);
		InvalidateRect(CRect(0,0,D_SIZE*2 + 4,D_SIZE*2 + 4),0);
		settitle(filename);
		m_ActionList.SetCurSel(generator.count()-1);
		SetCursor(0);
	}
}

void CTextureGeneratorDlg::settitle(CString title) {
	SetWindowText("Medieval Texture Generator beta version - [" + title + "]");
}

void CTextureGeneratorDlg::OnFileSaveTexture() 
{
	OPENFILENAME s;
	char filename[256];
	char file[256];
	char filter[256];
	memset(filename,0,256);
	memset(&s,0,sizeof(s));
	memset(file,0,256);
	memset(filter,0,256);

	s.lStructSize = sizeof(s);
	s.hwndOwner = *this;
	s.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
	//wildcard to display, returns with selected path\file
	strcpy(file,"*.6tx");
	s.lpstrFile = file;
	s.nMaxFile = 255;
	//returns with just file name
	s.lpstrFileTitle = filename;
	s.nMaxFileTitle = 255;
	//set the initial directory, otherwise uses current
	s.lpstrInitialDir = 0;
	//file type filter
	strcpy(filter,"Texture Scripts\0*.6tx\0\0");

	s.lpstrFilter = filter;
	s.nFilterIndex = 1;
	//dialog title
	s.lpstrTitle = "Save Texture Script";

	int res= GetSaveFileName(&s);

	if (res) {
		UpdateData(true);
		CString f(file),f2;
		f2=f;
		f2.MakeUpper();
		if (f2.Find(".6TX",0)==-1) f+=".6tx";
		generator.save(f, 0); //STRING2ID(m_TexID));
		settitle(filename);
	}	
}

void CTextureGeneratorDlg::OnRButtonDown(UINT nFlags, CPoint point) 
{
	int x=point.x;
	int y=point.y;
	x>>=8;
	y>>=8;
	if (x>=2 || y>=2) return;
	int num=(x&1) + (y?2:0);
	m_DataLayerList.SetCurSel(num);
	updatelabels();
	UpdateData(FALSE);

	CDialog::OnRButtonDown(nFlags, point);
}

void CTextureGeneratorDlg::OnUndo() 
{
	SetCursor(LoadCursor(NULL, IDC_WAIT));
	generator.undo();
	generator.tolist(m_ActionList);
	InvalidateRect(CRect(0, 0, D_SIZE*2+4, D_SIZE*2+4),0);
	SetCursor(0);
	m_ActionList.SetCurSel(generator.count()-1);
}

void CTextureGeneratorDlg::OnRedo() 
{
	generator.redo();
	generator.tolist(m_ActionList);
	InvalidateRect(CRect(0, 0, D_SIZE*2+4, D_SIZE*2+4),0);
	m_ActionList.SetCurSel(generator.count()-1);
}

void CTextureGeneratorDlg::OnDisplayAlpha() 
{
	UpdateData(TRUE);
	InvalidateRect(CRect(0, 0, D_SIZE*2+4, D_SIZE*2+4),0);
}
